﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Diagnostics;
using WorkflowDesigner.Workflow.Item;

namespace WorkflowDesigner.Workflow.Area
{
    public partial class DesignView : WorkflowBase
    {
        protected override void OnInit()
        {
            base.OnInit();
            this.LayoutRoot.Background = new SolidColorBrush(Colors.White);
            LayoutRoot.SizeChanged += new SizeChangedEventHandler(LayoutRoot_SizeChanged);
        }

        #region 标准事件 
        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);
            if (!App.IsCtrlKeyDown)
            {
                foreach (UIElement elem in LayoutRoot.Children)
                {
                    WorkflowBase body = elem as WorkflowBase;
                    if (body != null)
                    {
                        body.IsFocus = false;
                    }
                }
            }
        }

        void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (lsGridLine != null)
            {
                // 大小变化了，原来的线条长度和宽度会有问题。
                // 所以这里需要重新创建他们。
                foreach (Line item in lsGridLine)
                {
                    LayoutRoot.Children.Remove(item);
                }
                lsGridLine.Clear();
                this.ShowGridLine(this.IsGridLineShow);
            }
        }

        void DesignView_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            ScrollView.Width = this.ActualWidth;
            ScrollView.Height = this.ActualHeight;
            LayoutRoot.Width = this.ScrollView.Width;
            LayoutRoot.Height = this.ScrollView.Height;
            this.TryResize();
        }
        #endregion

        #region 尝试修正滚动条的位置和大小
        /// <summary>
        /// 尝试修正滚动条的位置和大小
        /// </summary>
        public void TryResize()
        {
            double dWidth = 0.0;
            double dHeight = 0.0;
            LayoutRoot.SetValue(Canvas.TopProperty, 0.0);
            LayoutRoot.SetValue(Canvas.LeftProperty, 0.0);
            foreach (UIElement elem in LayoutRoot.Children)
            {
                WorkflowBase item = elem as WorkflowBase;
                if (item != null)
                {
                    Point ptPos = item.Location;
                    Size size = item.RealSize;
                    dWidth = Math.Max(dWidth, ptPos.X + size.Width);
                    dHeight = Math.Max(dHeight, ptPos.Y + size.Height);
                }
            }
            // 这里的数字是为了弥补误差，留出部分边界上的空白
            double dSpace = 20.0;
            if (dWidth > this.ScrollView.ViewportWidth)
            {
                this.ScrollView.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
                LayoutRoot.Width = dWidth + dSpace;
            }
            else
            {
                this.ScrollView.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                LayoutRoot.Width = this.ScrollView.ViewportWidth;
            }
            if (dHeight > this.ScrollView.ViewportHeight)
            {
                this.ScrollView.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
                LayoutRoot.Height = dHeight + dSpace;
            }
            else
            {
                this.ScrollView.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
                LayoutRoot.Height = this.ScrollView.ViewportHeight;
            }
        }
        #endregion

        #region 修改节点状态和删除节点

        public void DeleteSelectedFlowItem()
        {
            foreach (UIElement item in LayoutRoot.Children)
            {
                WorkflowBase body = item as WorkflowBase;
                if ((body != null) && body.IsFocus)
                {
                    body.OnDelete();
                }
            }
        }

        public void DeleteFlowItem(WorkflowBase item)
        {
            LayoutRoot.Children.Remove(item as UIElement);
        }

        public void SetFlowItemFocus(WorkflowBase item)
        {
            if (!App.IsCtrlKeyDown)
            {
                foreach (UIElement elem in LayoutRoot.Children)
                {
                    WorkflowBase body = elem as WorkflowBase;
                    if ((body != null) && body.IsFocus && (item != body))
                    {
                        body.IsFocus = false;
                    }
                }
            }
        }
        #endregion

        #region 添加节点
        public void AddFlowItem(WorkflowBase item)
        {
            this.LayoutRoot.Children.Add(item);
            //item.IsFocus = true;
            item.BringToTop();
            TryResize();
        }

        public void AddFlowItem(WorkflowBase itemForCopy, Point ptAdd)
        {
            WorkflowBase item = null;
            switch (itemForCopy.ItemType)
            {
                case FlowItemType.Condition:
                    item = new FlowCondition();
                    Debug.WriteLine("AddFlowItem FlowCondition");
                    break;
                case FlowItemType.End:
                    item = new FlowEnd();
                    Debug.WriteLine("AddFlowItem FlowEnd");
                    break;
                case FlowItemType.Normal:
                    item = new FlowNormal();
                    Debug.WriteLine("AddFlowItem FlowNormal");
                    break;
                case FlowItemType.Start:
                    item = new FlowStart();
                    Debug.WriteLine("AddFlowItem FlowStart");
                    break;
                default:
                    break;
            }
            if (item != null)
            {
                this.LayoutRoot.Children.Add(item);
                item.MoveTo(ptAdd.X, ptAdd.Y);
                //item.IsFocus = true;
                item.BringToTop();
                TryResize();
            }
        }
        #endregion

        #region 按照指定条件查找节点

        public WorkflowBase FindItemMouseOver()
        {
            WorkflowBase objFind = null;
            foreach (UIElement elem in LayoutRoot.Children)
            {
                WorkflowBase item = elem as WorkflowBase;
                if ((item != null) && (item.IsMouseOver))
                {
                    if (objFind != null)
                    {
                        double dZindexNew = (double)item.GetValue(Canvas.ZIndexProperty);
                        double dZindexOld = (double)objFind.GetValue(Canvas.ZIndexProperty);
                        if (dZindexNew > dZindexOld)
                        {
                            objFind = item;
                        }
                    }
                    else
                    {
                        objFind = item;
                    }
                }
            }
            return objFind;
        }

        public WorkflowBase FindItemByPoint(Point ptSearch)
        {
            WorkflowBase objFind = null;
            foreach (UIElement elem in LayoutRoot.Children)
            {
                WorkflowBase item = elem as WorkflowBase;
                if (item != null)
                {
                    Point ptLocation = item.Location;
                    Rect rt = new Rect(ptLocation, item.RealSize);
                    if (Utility.PtInRect(rt, ptSearch))
                    {
                        if (objFind != null)
                        {
                            double dZindexNew = (double)item.GetValue(Canvas.ZIndexProperty);
                            double dZindexOld = (double)objFind.GetValue(Canvas.ZIndexProperty);
                            if (dZindexNew > dZindexOld)
                            {
                                objFind = item;
                            }
                        }
                        else
                        {
                            objFind = item;
                        }
                    }
                }
            }
            return objFind;
        }
        #endregion

        /// <summary>
        /// 判断两个节点之间是否可以连接
        /// </summary>
        /// <param name="itemFrom"></param>
        /// <param name="itemTo"></param>
        /// <returns>
        /// true : 可以连接
        /// false: 不可以连接
        /// </returns>
        public bool CheckNodeLink(WorkflowBase itemFrom, WorkflowBase itemTo)
        {
            bool canLink = true;
            if ((itemTo.ItemType == FlowItemType.Beeline)
                    || (itemTo.ItemType == FlowItemType.Start)
                    || (itemTo.ItemType == FlowItemType.Unknown))
            {
                canLink = false;
                return canLink;
            }
            foreach (UIElement elem in LayoutRoot.Children)
            {
                WorkflowBase item = elem as WorkflowBase;
                if ((item != null) && (item.ItemType == FlowItemType.Beeline))
                {
                    FlowBeeline line = item as FlowBeeline;
                    if (line != null)
                    {
                        if ((line.StartNode == itemFrom)
                            && (line.EndNode == itemTo))
                        {
                            MessageBox.Show("流程之间已经存在关联!", "警告", MessageBoxButton.OK);
                            canLink = false;
                            break;
                        }
                        else if ((line.StartNode == itemTo)
                            && (line.EndNode == itemFrom))
                        {
                            MessageBox.Show("流程之间已经存在关联!", "警告", MessageBoxButton.OK);
                            canLink = false;
                            break;
                        }
                    }
                }
            }
            return canLink;
        }
    }
}
